﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Threading.Tasks;

namespace MishraReader.Entities
{
    [ContractClass(typeof(IGoogleReaderConnectorContract))]
    public interface IGoogleReaderConnector : INotifyPropertyChanged
    {
        DateTime ConnectedAt { get; }
        int MaxItemsCount { get; set; }

        GoogleReaderConnectorStatus Status { get; }

        string UserName { get; }

        Task Connect(string login, string pass);
        void Disconnect();
        Task<Tuple<bool, int>> UpdateUnreadCountAsync(SubscriptionsList list);
        Task<SubscriptionsList> GetSubscriptionsListAsync();
        Task<ItemsList> LoadAllItemsAsync(SubscriptionsList subscriptionsList, IGoogleReaderStream category, string continuationToken, int pageSize);
        Task<ItemsList> LoadStarredItemsAsync(SubscriptionsList subscriptionsList, string continuationToken, int pageSize);
        Task<ItemsList> LoadUnreadItemsAsync(SubscriptionsList subscriptionsList, IGoogleReaderStream category, string continuationToken, int pageSize);
        Task MarkAllAsReadAsync(IGoogleReaderStream subscription);
        Task MarkItemAsReadAsync(Item item);
        Task MarkItemAsStarredAsync(Item item);
        Task MarkItemAsUnreadAsync(Item item);
        Task SetSortPreferenceAsync(bool desc);
        Task UnmarkItemAsStarredAsync(Item item);
    }

    [ContractClassFor(typeof(IGoogleReaderConnector))]
    internal abstract class IGoogleReaderConnectorContract : IGoogleReaderConnector
    {
        public abstract DateTime ConnectedAt { get; }

        public int MaxItemsCount
        {
            get 
            {
                Contract.Ensures(Contract.Result<int>() > 0);
                return default(int);
            }
            set
            {

                Contract.Requires(value > 0);
            }
        }

        public abstract GoogleReaderConnectorStatus Status { get; }

        public abstract string UserName { get; }

        public Task Connect(string pass, string login)
        {
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(pass));
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(login));

            return null;
        }

        public abstract void Disconnect();
        public abstract Task<Tuple<bool, int>> UpdateUnreadCountAsync(SubscriptionsList list);

        public Task<SubscriptionsList> GetSubscriptionsListAsync()
        {
            Contract.Ensures(Contract.Result<Task<SubscriptionsList>>() != null);
            return null;
        }

        public Task<ItemsList> LoadAllItemsAsync(SubscriptionsList subscriptionsList, IGoogleReaderStream category, string continuationToken, int pageSize)
        {
            Contract.Requires<ArgumentNullException>(subscriptionsList != null, "subscriptionsList");
            Contract.Requires<ArgumentOutOfRangeException>(pageSize > 0);

            return default(Task<ItemsList>);
        }

        public Task<ItemsList> LoadStarredItemsAsync(SubscriptionsList subscriptionsList, string continuationToken, int pageSize)
        {
            Contract.Requires<ArgumentNullException>(subscriptionsList != null, "subscriptionsList");
            Contract.Requires<ArgumentOutOfRangeException>(pageSize > 0);

            return default(Task<ItemsList>);
        }

        public Task<ItemsList> LoadUnreadItemsAsync(SubscriptionsList subscriptionsList, IGoogleReaderStream category, string continuationToken, int pageSize)
        {
            Contract.Requires<ArgumentNullException>(subscriptionsList != null, "subscriptionsList");
            Contract.Requires<ArgumentOutOfRangeException>(pageSize > 0);

            return default(Task<ItemsList>);
        }

        public Task MarkAllAsReadAsync(IGoogleReaderStream subscription)
        {
            return null;
        }

        public Task MarkItemAsReadAsync(Item item)
        {
            Contract.Requires<ArgumentNullException>(item != null, "item");
            return null;
        }

        public Task MarkItemAsStarredAsync(Item item)
        {
            Contract.Requires<ArgumentNullException>(item != null, "item");
            return null;
        }

        public Task MarkItemAsUnreadAsync(Item item)
        {
            Contract.Requires<ArgumentNullException>(item != null, "item");

            return null;
        }

        public abstract Task SetSortPreferenceAsync(bool desc);

        public Task UnmarkItemAsStarredAsync(Item item)
        {
            Contract.Requires<ArgumentNullException>(item != null, "item");

            return null;
        }


        public event PropertyChangedEventHandler PropertyChanged
        {
            add {  }
            remove {  }
        }
    }
}